<template>
  <ZgDialog
    :width="batch.width"
    :top="batch.top"
    :title="batch.title"
    v-model="showAdd"
    @ok="onAddOk"
    :confirmLoading="loading"
  >
    <div class="menu-assign-table">
      <a-spin :spinning="loading">
        <a-table
          :columns="columns"
          :data-source="tableData"
          :pagination="false"
          :children-column-name="null"
          :row-key="(record, index) => `row-${index}`"
          size="small"
          bordered
        >
          <template slot="index" slot-scope="text, record, index">
            {{ index + 1 }}
          </template>
          <template slot="parentMenu" slot-scope="text, record">
            <a-checkbox
              :checked="record.parentChecked"
              :indeterminate="record.indeterminate"
              @change="(e) => handleParentChange(e, record)"
            >
              {{ record.name }}
            </a-checkbox>
          </template>
          <template slot="childMenu" slot-scope="text, record">
            <div v-if="record.children && record.children.length > 0">
              <div v-for="child in record.children" :key="`${record.id}-${child.id}`" class="child-menu-item">
                <a-checkbox
                  :checked="child.checked"
                  @change="(e) => handleChildChange(e, child, record)"
                >
                  {{ child.name }}
                </a-checkbox>
              </div>
            </div>
            <span v-else class="no-children">无子菜单</span>
          </template>
        </a-table>
      </a-spin>
    </div>
  </ZgDialog>
</template>

<script>
export default {
  name: 'RoleMenuBatch',
  data () {
    return {
      showAdd: false,
      obj: null,
      loading: false,
      batch: {
        width: '80%',
        top: '5%',
        title: '分配菜单'
      },
      columns: [
        {
          title: '序号',
          dataIndex: 'index',
          key: 'index',
          width: 60,
          scopedSlots: { customRender: 'index' }
        },
        {
          title: '父菜单',
          dataIndex: 'parentMenu',
          key: 'parentMenu',
          width: '30%',
          scopedSlots: { customRender: 'parentMenu' }
        },
        {
          title: '子菜单',
          dataIndex: 'childMenu',
          key: 'childMenu',
          width: '70%',
          scopedSlots: { customRender: 'childMenu' }
        }
      ],
      tableData: []
    }
  },
  computed: {
    // 获取所有选中的菜单ID
    selectedMenuIds () {
      const selectedMenus = []
      this.tableData.forEach(parent => {
        if (parent.parentChecked) {
          selectedMenus.push(parent.id)
        }
        parent.children.forEach(child => {
          if (child.checked) {
            selectedMenus.push(child.id)
          }
        })
      })
      return selectedMenus
    }
  },
  methods: {
    /**
     * 打开对话框并加载数据
     * @param {Object} val - 包含角色信息和已分配菜单数据的对象
     */
    open (val) {
      this.showAdd = true
      this.obj = val.val
      this.loading = true

      this.loadMenuData(val)
    },

    /**
     * 加载菜单数据
     * @param {Object} val - 传入的参数
     */
    loadMenuData (val) {
      this.$http.get('/zg-system/menu/list', {}, res => {
        this.processMenuData(res, val)
        this.loading = false
      })
    },

    /**
     * 处理菜单数据
     * @param {Array} menuList - 原始菜单数据
     * @param {Object} val - 传入的参数
     */
    processMenuData (menuList, val) {
      // 只显示有子菜单的父菜单
      this.tableData = menuList
        .filter(item => item.children && item.children.length > 0)
        .map(item => this.createParentMenu(item))

      // 设置选中状态
      this.setSelectedState(val)
    },

    /**
     * 创建父菜单对象
     * @param {Object} item - 菜单项
     * @returns {Object} 处理后的父菜单对象
     */
    createParentMenu (item) {
      return {
        id: item.id,
        name: item.name,
        code: item.code,
        parentChecked: false,
        indeterminate: false,
        children: item.children.map(child => ({
          ...child,
          checked: false
        }))
      }
    },

    /**
     * 设置选中状态
     * @param {Object} val - 传入的参数
     */
    setSelectedState (val) {
      if (!val?.data || !Array.isArray(val.data)) {
        return
      }

      const selectedMenuIds = val.data.map(item => item.menuId)

      this.tableData.forEach(parent => {
        this.updateParentSelection(parent, selectedMenuIds)
      })
    },

    /**
     * 更新父菜单的选中状态
     * @param {Object} parent - 父菜单对象
     * @param {Array} selectedMenuIds - 选中的菜单ID列表
     */
    updateParentSelection (parent, selectedMenuIds) {
      // 检查父菜单是否在选中列表中
      if (selectedMenuIds.includes(parent.id)) {
        parent.parentChecked = true
      }

      // 检查子菜单并统计选中数量
      let checkedChildrenCount = 0
      parent.children.forEach(child => {
        if (selectedMenuIds.includes(child.id)) {
          child.checked = true
          checkedChildrenCount++
        }
      })

      // 设置父菜单的半选状态
      this.updateParentIndeterminateState(parent, checkedChildrenCount)
    },

    /**
     * 更新父菜单的半选状态
     * @param {Object} parent - 父菜单对象
     * @param {number} checkedChildrenCount - 选中的子菜单数量
     */
    updateParentIndeterminateState (parent, checkedChildrenCount) {
      if (checkedChildrenCount > 0 && checkedChildrenCount < parent.children.length) {
        parent.indeterminate = true
      } else if (checkedChildrenCount === parent.children.length) {
        parent.parentChecked = true
        parent.indeterminate = false
      }
    },

    /**
     * 关闭对话框
     */
    close () {
      this.showAdd = false
      this.tableData = []
      this.obj = null
    },

    /**
     * 确认操作
     */
    onAddOk () {
      if (!this.obj?.id) {
        this.$message.error('角色信息不完整')
        return
      }

      const result = {
        menuIds: this.selectedMenuIds,
        roleId: this.obj.id
      }

      console.log('选中的菜单:', this.selectedMenuIds, this.obj, 'obj')

      // 触发 ok 事件，传递数据给父组件
      this.$emit('ok', result)

      // 关闭对话框
      this.close()
    },

    /**
     * 处理父菜单选中状态变化
     * @param {Event} e - 事件对象
     * @param {Object} record - 父菜单记录
     */
    handleParentChange (e, record) {
      record.parentChecked = e.target.checked
      record.indeterminate = false

      // 更新所有子菜单的选中状态
      record.children.forEach(child => {
        child.checked = e.target.checked
      })
    },

    /**
     * 处理子菜单选中状态变化
     * @param {Event} e - 事件对象
     * @param {Object} child - 子菜单对象
     * @param {Object} record - 父菜单记录
     */
    handleChildChange (e, child, record) {
      child.checked = e.target.checked

      // 更新父菜单的选中状态
      this.updateParentState(record)
    },

    /**
     * 更新父菜单状态
     * @param {Object} record - 父菜单记录
     */
    updateParentState (record) {
      const allChildrenChecked = record.children.every(c => c.checked)
      const someChildrenChecked = record.children.some(c => c.checked)

      if (allChildrenChecked) {
        record.parentChecked = true
        record.indeterminate = false
      } else if (someChildrenChecked) {
        record.parentChecked = false
        record.indeterminate = true
      } else {
        record.parentChecked = false
        record.indeterminate = false
      }
    }
  }
}
</script>

<style scoped>
.menu-assign-table {
  max-height: 500px;
  overflow-y: auto;
}

.child-menu-item {
  margin-bottom: 8px;
  padding: 4px 8px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border-left: 3px solid #1890ff;
}

.child-menu-item:last-child {
  margin-bottom: 0;
}

.no-children {
  color: #999;
  font-style: italic;
}

.ant-table-tbody > tr > td {
  padding: 8px;
  vertical-align: top;
}

.ant-checkbox-wrapper {
  font-weight: 500;
}
</style>
